package gl.java.umsp.client;

import gl.java.umsp.ErrCode;
import gl.java.umsp.Umsp;
import gl.java.umsp.UmspHeader;
import gl.java.umsp.bean.Match;
import gl.java.umsp.bean.MatchResult;
import gl.java.umsp.match.MatchType;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;

import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;


@Slf4j
@ChannelHandler.Sharable
public class UmspClientHandler extends SimpleChannelInboundHandler<UmspHeader> {
    private ByteBuf buf;
    private volatile AtomicInteger msgIndex = new AtomicInteger();
    private MatchResult matchResult;
    private  int userID  = new Random().nextInt(100);
    @Override
    public void channelActive(final ChannelHandlerContext ctx) throws InterruptedException {
        log.info("channelActive:" + ctx.channel().remoteAddress());
        int gameID = 0;

        Thread.sleep(300);
        log.info("============================");
        log.info("==== userID:" + userID + " to login");
        log.info("============================");
        Umsp.returnLogin(ctx.channel(), gameID, userID, "token");
        Umsp.returnMatch(ctx.channel(), new Match(MatchType.RANDOM));

    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        buf = ctx.alloc().buffer(4); // (1)
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        buf.release(); // (1)
        buf = null;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, UmspHeader msg)
            throws Exception {
        if (msg.cmd == Umsp.CMD_MSG||msg.cmd == Umsp.CMD_MSG_RSP) {
            msgIndex.incrementAndGet();
            Thread.sleep(3000);
            log.info("==== [ Rsp Other User Msg ] ==== ::: "+ new String(msg.getPayload()));
            Umsp.returnBoradcastStringMsg(Umsp.CMD_MSG, matchResult, "==== I am "+userID+" ====" ,ctx.channel());
        } else if (msg.cmd == Umsp.CMD_MATCH_RSP) {
            MatchResult result = MatchResult.fromJson(new String(msg.getPayload()), MatchResult.class);
            this.matchResult = result;
            log.info("========== match result:" + result);
            if (result.isSuccess) {
                Umsp.returnMsg(new UmspHeader(Umsp.CMD_ROOM_ENTER, result, result.room.roomID.getBytes()), ctx.channel());
            }
        }else if(msg.cmd == Umsp.CMD_LOGIN_RSP){
            log.info("===== Login Success =====");
        }else if(msg.cmd == Umsp.CMD_ROOM_USER_CHANGED){
            log.error("User Room Changed : "+ new String (msg.getPayload()));
            Umsp.returnBoradcastStringMsg(Umsp.CMD_MSG, matchResult, "hello world " + msgIndex, ctx.channel());
        }else if(msg.cmd == Umsp.CMD_ERR){
            log.warn("recv ErrCode: "+ msg.gameID+","+ErrCode.toString(msg.gameID));
        }
        else {
            log.warn("recv unknown msg: "+msg);
        }

    }
}